﻿using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization;

namespace Microsoft.WowAddonStudio.FrameXml.Components.Support
{
    public class SerializationObjectFactory
    {
        private const string resourceRootPath = "Microsoft.WowAddonStudio.FrameXml.Components.Resources.SerializationObjectFactory";

        public readonly static SerializationObjectFactory Default = new SerializationObjectFactory();

        /// <summary>
		/// Creates the serialization object.
		/// </summary>
		/// <typeparam name="TSerializationObject">The type of the serialization object.</typeparam>
		/// <returns></returns>
    	public TSerializationObject CreateSerializationObject<TSerializationObject>() where TSerializationObject : SerializationObject, new()
        {
            return (TSerializationObject)this.CreateSerializationObject(typeof(TSerializationObject));
        }

		/// <summary>
		/// Creates the serialization object.
		/// </summary>
		/// <param name="serializationObjectType">Type of the serialization object.</param>
		/// <returns></returns>
        public SerializationObject CreateSerializationObject(Type serializationObjectType)
        {
            if (serializationObjectType == null)
                throw new ArgumentNullException("serializationObjectType");
            if (typeof(SerializationObject).IsSubclassOf(serializationObjectType))
                throw new ArgumentException("Type is not a subclass of SerializationObject.");

            // Construct path to resource
            var resourcePath = String.Format(CultureInfo.InvariantCulture, "{0}.{1}.xml", resourceRootPath, serializationObjectType.Name);

            // Create XML serializer
            var serializer = new XmlSerializer(serializationObjectType);

            // Get manifest resource stream and deserialize serialization object
            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath))
            {
                if (stream != null)
                    return (SerializationObject)serializer.Deserialize(stream);
            }

            return (SerializationObject)Activator.CreateInstance(serializationObjectType);
        }
    }
}
